﻿#define IncrementalGenerator

using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using UIOC.CodeAnalysis.Generators;

namespace UIOC.Observable.CodeAnalysis.Generators;

#if IncrementalGenerator
#else
internal sealed class UIOCObservableReceiver : SyntaxReceiver {

    public override void OnVisitSyntaxNode(SyntaxNode syntaxNode) {
        if (syntaxNode is InterfaceDeclarationSyntax interfaceDeclaration && interfaceDeclaration.AttributeLists.Any()) {
            CandidateInterfaces.Add(interfaceDeclaration);
        } else if (syntaxNode is ClassDeclarationSyntax classDeclaration) {
            CandidateClasses.Add(classDeclaration);
        }
    }
}
#endif

[Generator]
internal sealed class UIOCObservableGenerator : Generator {

    public const string Leading = $"// <auto-generated> This file was automatically generated by {nameof(UIOCObservableGenerator)}. </auto-generated>";

#if IncrementalGenerator
#else
    public override void Initialize(GeneratorInitializationContext context) => context.RegisterForSyntaxNotifications(() => new UIOCObservableReceiver());
#endif

    protected override void Execute(
#if IncrementalGenerator
        IncrementalGeneratorInitializationContext context,
        IncrementalValueProvider<ImmutableArray<ClassDeclarationSyntax>> candidateClasses,
        IncrementalValueProvider<ImmutableArray<InterfaceDeclarationSyntax>> candidateInterfaces
#else
        GeneratorExecutionContext context,
        ImmutableArray<ClassDeclarationSyntax> candidateClasses,
        ImmutableArray<InterfaceDeclarationSyntax> candidateInterfaces
#endif
    ) {
        // 1. 生成 Model 类
        var generatedModels = Generate(context, candidateClasses, ModelGenerator.GenerateModel);

        // 注册所有生成的源代码
        Register<
            ImmutableArray<ModelGenerator.GeneratedInfo>,
            ModelGenerator.GeneratedInfo
        >(context, generatedModels, info => info.GeneratedSource);
    }
}